'''验证token'''
from collections import namedtuple
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer,BadSignature,SignatureExpired
from flask import current_app, g, request

from app.libs.error_code import AuthFailed, Forbidden

# 创建一个User对象
from app.libs.scope import is_in_scope

User=namedtuple('User',['uid','ac_type','scope'])

# auth=HTTPBasicAuth()
auth=HTTPTokenAuth(scheme='test')

@auth.verify_token
def verify_token(token):
    # header使用方式，这个test和 token直接有空格
    #key value
    #Authorization test eyJhbGciOiJIUzUxMiIs
    user_info=verify_auth_token(token)
    if not user_info:
        return False
    else:
        g.user=user_info
        return True

# @auth.verify_password
# def verify_password(token,password):
#     print('token:{},password:{}'.format(token,password))
#     #token 直接把token当账号传递进来
#     #HTTP 账号密码
#     #header key:value
#     '''使用规范，header里面加入一组键值对格式如下'''
#     #key=Authorization
#     #value=basic base64(账号:密码)  https://www.bt.cn/tools/encrybase.html
#     token='eyJhbGciOiJIUzUxMiIsImlhdCI6MTYzNzY1MTAzMSwiZXhwIjoxNjQwMjQzMDMxfQ.eyJ1aWQiOjEsInR5cGUiOjEwMCwic2NvcGUiOiJBZG1pblNjb3BlIn0.Ip1MKu62CfFIExWi1obFemQB5Bt6W235RiieiatXgwJnPWl0UAg2Z8Ox6ld8fxtKjeDmCUPp3KLfHPjzy_plhw'
#     user_info=verify_auth_token(token)
#     if not user_info:
#         return False
#     else:
#         g.user=user_info
#         return True


def verify_auth_token(token):
    s=Serializer(current_app.config['SECRET_KEY'])
    try:
        print('token:{}'.format(token))
        data=s.loads(token)
    except BadSignature:#捕捉到特定异常说明是token不合法的
        raise AuthFailed(msg='token is invalid',error_code=1002)
    except SignatureExpired:#捕捉是否过期的异常
        raise AuthFailed(msg='token is expired',error_code=1003)

    uid=data['uid']
    ac_type=data['type']
    scope=data['scope']
    #request 视图函数 request.endpoint拿到视图函数
    allow=is_in_scope(scope,request.endpoint)
    print(request.endpoint)
    if not allow:
        raise Forbidden()
    return User(uid,ac_type,scope)
